package ratson.genimageexplorer.gui.dialogs;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.tree.TreePath;

import org.mozilla.javascript.serialize.ScriptableInputStream;

import ratson.genimageexplorer.generators.janino.ScriptReference;
import ratson.genimageexplorer.gui.utils.AutoIndentAction;
import ratson.genimageexplorer.gui.utils.FilesTreeModel;

/**
 *
 * @author  dim
 */
public class EditScriptDialog extends javax.swing.JDialog {

	/** Creates new form EditScriptDialog */
	public EditScriptDialog(java.awt.Frame parent, boolean modal) {
		super(parent, modal);
		createActions();
		initComponents();
		addListeners();
		setSize(600, 400);
		setLocationRelativeTo(parent);
	}
	//private boolean modalResult;

	private String scriptsDir = ".";

	private Action actnSave;
	
	private void createActions() {

		actnOK=new AbstractAction("OK"){
			public void actionPerformed(ActionEvent e) {
				//modalResult=true;
				updateScript();
				setVisible(false);
			}
		};
		actnCancel=new AbstractAction("Cancel"){
			public void actionPerformed(ActionEvent e) {
//				modalResult=false;
				setVisible(false);
			}
		};
		actnCompile=new AbstractAction("Compile"){
			public void actionPerformed(ActionEvent e) {

			}
		};
		actnSaveAs =new AbstractAction("Save as"){
			public void actionPerformed(ActionEvent e) {
				saveScriptAs();
			}
		}; 
		actnSave =new AbstractAction("Save"){
			public void actionPerformed(ActionEvent e) {
				saveScript();
			}
		}; 
	}

	/**Update the script code instance*/
	protected void updateScript() {
		
		script.set(txtScript.getText());
		if (script.changed)
			setTitle(script.getName()+" *");
	}
	
	private Action actnOK, actnCancel, actnCompile, actnAdd, actnSaveAs;

	private JButton btnSave;

	private JTree treeScripts;

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		Dimension maxBtnSize = new Dimension(Integer.MAX_VALUE, 30);
		
		
		treeScripts = new JTree (new FilesTreeModel(scriptsDir,"script"));
		
		btnAdd = new javax.swing.JButton();
		btnCompile = new javax.swing.JButton(actnCompile);
		//btnCancel = new javax.swing.JButton(actnCancel);
		btnOK = new javax.swing.JButton(actnOK);
		txtScript = new javax.swing.JTextArea();
		btnSaveAs = new JButton(actnSaveAs);
		btnSave = new JButton(actnSave);

		setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);


		btnAdd.setText("Add"); // NOI18N


		{//Set up auto-indent
			Action actionAutoIndent = new AutoIndentAction();
			txtScript.getInputMap(JComponent.WHEN_FOCUSED).put(
					KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
					"auto-indent");
			txtScript.getActionMap().put("auto-indent", actionAutoIndent);
		}
		
		//txtScript.setColumns(20);
		//txtScript.setRows(5);
		txtScript.setFont(new Font("monospaced",Font.PLAIN,12));


		
		
		Box upperBox = Box.createHorizontalBox();
		upperBox.add(btnSave);
		upperBox.add(btnSaveAs);
		
		
		getContentPane().add(upperBox, BorderLayout.NORTH);

		
		//lowerBox.add(btnCancel);
		
		
		JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
				new JScrollPane(treeScripts),
				new JScrollPane(txtScript));
		
	
		getContentPane().add(splitPane);

		{
			Box lowerBox = Box.createHorizontalBox();
			lowerBox.add(Box.createHorizontalGlue());
			lowerBox.add(btnOK);
			getContentPane().add(lowerBox,BorderLayout.SOUTH);
		}		
	}

	class ScriptRecord{
		public File script;
		public ScriptRecord(File script){
			this.script = script;
		}
		
		public String toString() {
			return script.getName();
		}
	}
	private void updateScriptsList(){
		
	}

	private void retrieveData(){
		script.set(txtScript.getText());
	}
	
	private void addListeners(){
		
		treeScripts.addMouseListener(new MouseAdapter(){
			@Override
			public void mouseClicked(MouseEvent arg0) {
				if (arg0.getClickCount() == 2){//doubleclick
					TreePath selPath = treeScripts.getSelectionPath();
					Object o = selPath.getPathComponent(selPath.getPathCount()-1);
					FilesTreeModel.TreeNode node =(FilesTreeModel.TreeNode)o;
					if (node.isLeaf()){
						System.out.println("Loading double-clicked item");
						loadScript(node.getFile());
					}
				}
			}
		});
	}

	protected void loadScript(File script) {
		
		if (this.script.changed){
			int rval = JOptionPane.showConfirmDialog(this, "Script was modified, do you want to save it first?", "Unsaved changes", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
			switch (rval){
			case JOptionPane.CANCEL_OPTION:
				return;
			case JOptionPane.YES_OPTION:
				saveScript();
				break;
			case JOptionPane.NO_OPTION:
				break;
			}
		}
		
		System.out.println("Loading script "+script.getName());
		try {
			this.script.load(script);
		} catch (FileNotFoundException e) {
			JOptionPane.showMessageDialog(this, "File not found.\n"+e.getLocalizedMessage());
			return;
		} catch (IOException e) {
			JOptionPane.showMessageDialog(this, "IO error when reading the file.\n"+e.getLocalizedMessage());
			return;
		}
		putData();
	}
	private void putData() {
		txtScript.setText(script.getScript());
		updateTitle();
	}

	private void saveScript(){
		
		if (script.file == null){
			//file not set
			saveScriptAs();
			return;
		}
		
		retrieveData();
		try {
			script.save();
			updateTitle();
		} catch (FileNotFoundException e) {
			JOptionPane.showMessageDialog(this, "File not found.\n"+e.getLocalizedMessage());
			return;
		} catch (IOException e) {
			JOptionPane.showMessageDialog(this, "IO error when saving the file.\n"+e.getLocalizedMessage());
			return;
		}
	}
	
	private void saveScriptAs(){
		retrieveData();
		String res = JOptionPane.showInputDialog(this, "Enter new name", "Save script as", JOptionPane.PLAIN_MESSAGE);
		if (res == null)
			return;

		res = res.trim();
		
		String fname;
		if (!res.endsWith(".script"))
			fname = res+".script";
		else
			fname = res;
		
		File newFile = new File(fname);
		if (newFile.exists()){
			
			int rval = JOptionPane.showConfirmDialog(this, 
					"File exists", 
					String.format("File %s already exists. Overwrite it?", fname),
					JOptionPane.OK_CANCEL_OPTION
					);
			if (rval != JOptionPane.OK_OPTION){
				System.out.println("Save as cancelled");
				return;
			}
			
		}
		
		try {
			script.saveas(newFile);
			
		} catch (FileNotFoundException e) {
			JOptionPane.showMessageDialog(this, "File not found.\n"+e.getLocalizedMessage());
			return;
		} catch (IOException e) {
			JOptionPane.showMessageDialog(this, "IO error when saving the file.\n"+e.getLocalizedMessage());
			return;
		}
		updateScriptsList();
		updateTitle();
	}
	private void updateTitle() {
		setTitle(script.getName() );
	}
	// Variables declaration - do not modify
	private javax.swing.JButton btnAdd;
	private javax.swing.JButton btnCompile;
	private javax.swing.JButton btnCancel;
	private javax.swing.JButton btnSaveAs;
	private javax.swing.JButton btnOK;
	private javax.swing.JTextArea txtScript;
	// End of variables declaration

	private ScriptReference script = new ScriptReference();

	public void setScript(ScriptReference script) {
		this.script = script;
		txtScript.setText(script.script);
		updateTitle();
	}
	public ScriptReference getScript(){
		return script;
	}




}
